package com.cooperate.fly.controller;

import com.cooperate.fly.bo.DataRight;
import com.cooperate.fly.bo.Schema;
import com.cooperate.fly.bo.User;
import com.cooperate.fly.mapper.DataRightMapper;
import com.cooperate.fly.mapper.SchemaMapper;
import com.cooperate.fly.mapper.UserMapper;
import com.cooperate.fly.service.buildDB.BuildFieldService;
import com.cooperate.fly.service.buildDB.BuildSchemaService;
import com.cooperate.fly.util.SystemConstant;
import com.cooperate.fly.web.Result;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
 * Created by Stellar_Lee on 2016/4/18.
 */
@Controller
@RequestMapping("/schema")
@SessionAttributes(SystemConstant.USER_SESSION_KEY)
public class BuildSchemaController extends BaseController {
    @Resource
    private BuildSchemaService buildSchemaService;

    @Resource
    private BuildFieldService buildFieldService;

    @Autowired
    private SchemaMapper schemaMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private DataRightMapper dataRightMapper;

    @Value("#{propertiesReader['dReadAuth']}")
    private int readAuth;

    @Value("#{propertiesReader['dWriteAuth']}")
    private int writeAuth;

    @RequestMapping(value = "/list",method= RequestMethod.GET)
    public String listAll(Model model){
        model.addAttribute("schemaData", buildSchemaService.loadSchema());
        return "schema-design";
    }

    @RequestMapping(value="/create", method=RequestMethod.GET)
    @ResponseBody
    public Result add(@RequestParam(value="name", required=true) String name,
                      @RequestParam(value="type", required=true) int type,
                      @RequestParam(value="parentId", required=true) int parentId) {
        Schema schema=new Schema();
        schema.setName(name);
        schema.setType(type);
        schema.setParentId(parentId);
        return buildSchemaService.createSchemaNode(schema);
    }

    @RequestMapping(value="/update", method=RequestMethod.GET)
    @ResponseBody
    public Result update(Schema schema) {
        //update
        return buildSchemaService.updateSchemaNode(schema);
    }

    //if node is catalog, then delete all the son node
    @RequestMapping(value="/delete")
    @ResponseBody
    public Result delete(@RequestParam(value="id", required=true) int id) {
        return buildSchemaService.deleteSchemaNode(id);
    }

    @RequestMapping(value="/setDatabase")
    @ResponseBody
    public Result setDatabase(@RequestParam(value="id", required=true) int id) {
        return buildSchemaService.setDatabase(id);
    }

    //the interface of get data
    @RequestMapping(value = "/name/{schemaNames}", produces = "application/json;charset=utf-8",method = RequestMethod.GET,params = "action=get")
    @ResponseBody
    public String getSchema(@PathVariable String schemaNames){
        return buildSchemaService.parseSchemaUrl(schemaNames);
    }

    @RequestMapping(value = "/name/{schemaNames}/field/name/{fieldNames}", produces = "application/json;charset=utf-8",method = RequestMethod.GET,params = "action=get")
    @ResponseBody
    public String getField(@PathVariable String schemaNames,@PathVariable String fieldNames){
        return buildFieldService.parseFieldUrl(schemaNames,fieldNames);
    }

    @ResponseBody
     @RequestMapping("/getSchemaRemark3")
     public Result getSchemaRemark3(int id) {
        return buildSchemaService.getSchemaRemark3(id);
    }

    @ResponseBody
    @RequestMapping("/getSchemaInfo")
    public Result getSchemaInfo(int id) {
        //info包括remark2图片说明和remark3的文字说明
        return buildSchemaService.getSchemaInfo(id);
    }
    @ResponseBody
    @RequestMapping("/setSchemaRemark3")
    public Result getSchemaRemark3(int id,String remark3) {
        return buildSchemaService.setSchemaRemark3(id, remark3);
    }

    /**
     * schemaDescribePic文件夹中通过schemaId来进行描述图片的存储
     * @param schemaId
     * @param multipartRequest
     * @param request
     * @param response
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping(value = "/savePicture",method = RequestMethod.POST)
    public void savePicture(@RequestParam(value="schemaId", required=true) int schemaId,MultipartHttpServletRequest multipartRequest,
                           HttpServletRequest request,HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=UTF-8");
        int resultCode=500;
        try{
            for(Iterator it = multipartRequest.getFileNames();it.hasNext();){
                String key = (String)it.next();
                MultipartFile file = multipartRequest.getFile(key);
                if(!file.isEmpty()){
                    String postfix=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.'));
                    String fileName=file.getOriginalFilename().substring(0,file.getOriginalFilename().lastIndexOf('.'));
                    if(fileName.length()>490){
                        return;//名字不能够大于存储的空间
                    }
                    String filePath=request.getSession().getServletContext().getRealPath("/") + "schemaDescribePic"+File.separator;
                    File pathFile=new File(filePath);
                    if(!pathFile.exists()){
                        pathFile.mkdirs();
                    }
                    //后台存储的时候加上schemaId来唯一标记，也可以加上时间戳
                    File tempFile=new File(filePath+fileName+"_"+schemaId+postfix);
                    if(tempFile.exists()){
                        tempFile.delete();//如果之前存在描述图片则删除进行更新
                    }
                    OutputStream out=new FileOutputStream(tempFile);
                    //名字不能够超过500个字符
                    Schema schema=schemaMapper.selectByPrimaryKey(schemaId);
                    schema.setRemark2(fileName+"_"+schemaId+postfix);
                    schemaMapper.updateByPrimaryKey(schema);
                    out.write(file.getBytes());
                    out.close();
                    resultCode=200;
                }
            }
            response.getWriter().print(resultCode);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 加载待分配权限的用户
     * @return
     */
    @RequestMapping(value = "/loadAuthUsers", produces = "application/json;charset=utf-8")
    @ResponseBody
    public List<User> loadAuthUsers(int id){
        List<User> users = userMapper.selectAll();
        List<User>  result=new ArrayList<User>();
        for (User user : users){
            //超级用户和数据策划者不在这个名单中
            if(user.getRoleId()>2) {
                result.add(user);
            }
        }
        return result;
    }


    /**
     * 加载待分配权限的用户
     * @return
     */
    @RequestMapping(value = "/loadReadUsers", produces = "application/json;charset=utf-8")
    @ResponseBody
    public List loadReadUsers(int schemaId){
        List<DataRight> temp=dataRightMapper.selectBySchemaAndType(schemaId,readAuth);
        List<User> users=new ArrayList<User>();
        for(DataRight dr:temp){
            users.add(userMapper.selectByPrimaryKey(dr.getUserid()));
        }
       return users;
    }
    /**
     * 加载待分配权限的用户
     * @return
     */
    @RequestMapping(value = "/loadWriteUsers", produces = "application/json;charset=utf-8")
    @ResponseBody
    public List loadWriteUsers(int schemaId){
        List<DataRight> temp=dataRightMapper.selectBySchemaAndType(schemaId,writeAuth);
        List<User> users=new ArrayList<User>();
        for(DataRight dr:temp){
            users.add(userMapper.selectByPrimaryKey(dr.getUserid()));
        }
        return users;
    }

    /**
     * 加载待分配权限的用户
     * @return
     */
    @RequestMapping(value = "/saveAuthUsers", produces = "application/json;charset=utf-8")
    @ResponseBody
    public Result saveAuthUsers(int databaseId,String readIds,String writeIds){
        Result result=new Result();
        result.setSuccessful(false);
        ArrayList<DataRight> oldReadIds=dataRightMapper.selectBySchemaAndType(databaseId,readAuth);
        ArrayList<DataRight> oldWriteIds=dataRightMapper.selectBySchemaAndType(databaseId,writeAuth);
        //对读用户权限处理
        Set<Integer> rIdsList=new Gson().fromJson(readIds, new TypeToken<HashSet<Integer>>() {}.getType());
        Set<Integer> wIdsList=new Gson().fromJson(writeIds, new TypeToken<HashSet<Integer>>() {}.getType());
        if(rIdsList==null){
            rIdsList=new HashSet<Integer>();
        }
        if(wIdsList==null){
            wIdsList=new HashSet<Integer>();
        }
        Set<Integer> rDeleteList=new HashSet<Integer>();
        Set<Integer> wDeleteList=new HashSet<Integer>();
            for (DataRight dr : oldReadIds) {
                if (rIdsList.contains(dr.getUserid())) {
                    rIdsList.remove(dr.getUserid());
                } else {
                    rDeleteList.add(dr.getId());
                }
            }
            for (Integer rid : rIdsList) {
                DataRight dataRight = new DataRight();
                dataRight.setSchemaid(databaseId);
                dataRight.setType(readAuth);
                dataRight.setUserid(rid);
                dataRightMapper.insert(dataRight);
            }
            for(Integer id:rDeleteList){
                dataRightMapper.deleteByPrimaryKey(id);
            }

        for (DataRight dr : oldWriteIds) {
            if (wIdsList.contains(dr.getUserid())) {
                wIdsList.remove(dr.getUserid());
            } else {
                wDeleteList.add(dr.getId());
            }
        }
        for(Integer wid:wIdsList){
            DataRight dataRight=new DataRight();
            dataRight.setSchemaid(databaseId);
            dataRight.setType(writeAuth);
            dataRight.setUserid(wid);
            dataRightMapper.insert(dataRight);
        }

        for(Integer id:wDeleteList){
            dataRightMapper.deleteByPrimaryKey(id);
        }
        result.setSuccessful(true);
        return result;
    }
}
